package org.lex.swing.plaf.util;

import java.awt.Component;
import java.awt.Window;
import java.util.ArrayList;

import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.plaf.metal.DefaultMetalTheme;
import javax.swing.plaf.metal.MetalTheme;
import javax.swing.plaf.metal.OceanTheme;

import org.lex.swing.plaf.metal.theme.AquaMetalTheme;
import org.lex.swing.plaf.metal.theme.ContrastMetalTheme;
import org.lex.swing.plaf.metal.theme.GreenMetalTheme;
import org.lex.swing.plaf.metal.theme.KhakiMetalTheme;

public class LookAndFeelUtils {
	private static MetalTheme[] METAL_THEMES = null;

	private LookAndFeelUtils() {
	}

	public static void updateLookAndFeel(LookAndFeel lookAndFeel) {
		updateLookAndFeel(lookAndFeel, (Component[]) Window.getWindows());
	}

	public static void updateAllComponentsLookAndFeel(LookAndFeel lookAndFeel, Component... components) {
		if (null == components)
			components = Window.getWindows();
		updateLookAndFeel(lookAndFeel, components);
	}

	public static void updateLookAndFeel(final LookAndFeel lookAndFeel, final Component... components) {
		if (null == lookAndFeel)
			return;
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					UIManager.setLookAndFeel(lookAndFeel);
					if (null == components || 0 == components.length)
						return;
					for (Component c : components)
						if (null != c)
							SwingUtilities.updateComponentTreeUI(c);
				} catch (Exception e) {
				}
			}
		});
	}

	public static LookAndFeel[] getInstalledLookAndFeels() {
		LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels();
		ArrayList<LookAndFeel> list = new ArrayList<LookAndFeel>();
		for (int i = 0; i < info.length; i++) {
			LookAndFeel lnf = getLookAndFeel(info[i].getClassName());
			if (null != lnf)
				list.add(lnf);
		}
		return list.toArray(new LookAndFeel[0]);
	}

	public static LookAndFeel getLookAndFeel(String className) {
		/*
		 * get the look-and-feel instance from class-name. these codes mostly
		 * copied from UIManager.setLookAndFeel( String ) and
		 * SwingUtilities.loadSystemClass( String ) i don't get the real means
		 * of these codes ...
		 */
		try {
			Class<?> lnfClass = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
			return (LookAndFeel) lnfClass.newInstance();
		} catch (Exception e) {
			return null;
		}
	}

	public static synchronized MetalTheme[] getMetalThemes() {
		if (null == METAL_THEMES) {
			METAL_THEMES = new MetalTheme[] { new OceanTheme(), new DefaultMetalTheme(), new GreenMetalTheme(),
					new AquaMetalTheme(), new KhakiMetalTheme(), new ContrastMetalTheme() };
		}
		return METAL_THEMES;
	}
}
